package com.example.victory.filter;

import com.example.victory.utils.JsonHelper;
import com.example.victory.common.web.WebHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.lang.reflect.Method;
import java.util.Date;

/**
 * 全局返回值处理
 */
@ControllerAdvice
public class GlobalReturnValueHandler implements ResponseBodyAdvice<Object> {
    private static final Logger logger = LoggerFactory.getLogger(GlobalReturnValueHandler.class);

    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        return (returnType.getParameterType().equals(ResponseEntity.class));
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        if (body != null && selectedContentType.equals(MediaType.APPLICATION_JSON)) {
            try {
                Object responseObj = body;
                Class<?> clazz = responseObj.getClass();
                Method methodSetTimestamp = clazz.getMethod("setTimestamp", Long.class);
                Method methodSetMessage = clazz.getMethod("setMessage", String.class);
                Method methodGetCode = clazz.getMethod("getCode");
                Method methodSetCode = clazz.getMethod("setCode", Integer.class);

                // 设置统一的返回消息：timestamp
                if (methodSetTimestamp != null) {
                    methodSetTimestamp.invoke(responseObj, new Date().getTime());
                }
                // 设置成功执行的message
                if (methodGetCode != null && methodSetMessage != null) {
                    Integer code = (Integer) methodGetCode.invoke(responseObj);
                    if (code == null) {
                        methodSetCode.invoke(responseObj, 0);
                    }
                    if (code == null || code.intValue() == 0) {
                        methodSetMessage.invoke(responseObj, "请求执行成功");
                    }
                }
            } catch (NoSuchMethodException e) {
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
            }

            // 打印返回结果
            Boolean isDebug = SpringBootFilter.DebugThreadLocal.get();
            if (isDebug != null && isDebug.booleanValue()) {
                String json = JsonHelper.toPrettyJson(body);
                WebHelper.logEnd(json);
            }
        }

        return body;
    }
}
